/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package client;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Collections;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;

class Client implements Runnable {
  private int numport ;
  private String host ;
  private SSLSocket socket;
  private DataInputStream entree;
  private DataOutputStream sortie;
  private Menu_ImSSL_GUI gui ;
  private boolean connecte = false;

  public Client(int numport , String host) {
    this.numport = numport ;
    this.host = host ;
    connecte = false;
  }

  public boolean connecte() {
    return connecte;
  }

   public void run() {
        connection();
        while ( true ){
            try {
                short commande = entree.readShort();
                System.out.println(commande);
                traiterCommandes(commande);
            } catch (Exception ex) {
                new TraiteException(ex, "run");
            }
       }
    }



  public void connection() {
    try {
        SSLSocketFactory sf =(SSLSocketFactory)SSLSocketFactory.getDefault();
        socket = (SSLSocket)sf.createSocket(host, numport);
        System.out.println(socket.getSession().getCipherSuite());
        entree = new DataInputStream(socket.getInputStream());
        sortie = new DataOutputStream(socket.getOutputStream());


    } catch (UnknownHostException ex) {
         new TraiteException(ex,"Probleme Client connection : Le serveur ne répond pas");
    } catch (IOException ex) {
         new TraiteException(ex,"Probleme Client connection : Probleme d'entrées / sorties");
    }
  }

  public void traiterInscriptionChat(String pseudo, String password) throws NullPointerException, IOException {
    sortie.writeShort(CodeCommande.COMMANDE_INSCRIPTION_CHAT);
    sortie.writeUTF(pseudo);
    sortie.writeUTF(password);  
  }
  
  public void traiterConnectionChat(String pseudo, String password) throws NullPointerException, IOException {
    sortie.writeShort(CodeCommande.COMMANDE_CONNECTION_CHAT);
    sortie.writeUTF(pseudo);
    sortie.writeUTF(password);   
  }
  public void traiterRejoindreCanal(String nomCanal, String passwordCanal) throws NullPointerException, IOException {
    sortie.writeShort(CodeCommande.COMMANDE_CREER_REJOINDRE_CANAL);
    sortie.writeUTF(nomCanal);
    sortie.writeUTF(passwordCanal);
  }

    void addGui(Menu_ImSSL_GUI aThis) {
        this.gui = aThis ;
    }

    void bannir(String nomCanal, String pseudo) {
        try {
            sortie.writeShort(CodeCommande.COMMANDE_BANNIR_UTILISATEUR_CANAL);
            sortie.writeUTF(nomCanal);
            sortie.writeUTF(pseudo);
        } catch (IOException ex) {
            new TraiteException(ex, "envoyerMessage");
        }
    }

    void deBannir(String nomCanal, String pseudo) {
        try {
            sortie.writeShort(CodeCommande.COMMANDE_DEBANNIR_UTILISATEUR_CANAL);
            sortie.writeUTF(nomCanal);
            sortie.writeUTF(pseudo);
        } catch (IOException ex) {
            new TraiteException(ex, "envoyerMessage");
        }
    }

    void deOp(String nomCanal, String pseudo) {
        try {
            sortie.writeShort(CodeCommande.COMMANDE_SUPPRIMER_SUPERUTILISATEUR);
            sortie.writeUTF(nomCanal);
            sortie.writeUTF(pseudo);
        } catch (IOException ex) {
            new TraiteException(ex, "deOp");
        }
    }

   
    void closeSocket() {
       try {
        socket.close();
        System.exit(0);
        } catch (IOException ex) {
            new TraiteException(ex, "closeSocket");
        }
    }

    void deconnecterChat() {
        try {
            sortie.writeShort(CodeCommande.COMMANDE_DECONNECTION_CHAT);
            socket.close();
            System.exit(0);
        } catch (IOException ex) {
            new TraiteException(ex, "deconnecterChat");
        }
    }

    void dialoguer(String pseudo) {
        try {
            sortie.writeShort(CodeCommande.COMMANDE_DIALOGUER);
            sortie.writeUTF(pseudo);
        } catch (IOException ex) {
            new TraiteException(ex, "deconnecterChat");
        }
    }

    void envoyerMessage(String nomCanal, String msg)  {
        try {
            sortie.writeShort(CodeCommande.COMMANDE_ENVOYER_MESSAGE);
            sortie.writeUTF("#"+nomCanal);
            sortie.writeUTF(msg);
        } catch (IOException ex) {
            new TraiteException(ex, "envoyerMessage");
        }
        
    }

    void envoyerMessageUtilisateur(String pseudo, String msg) {
        try {
            sortie.writeShort(CodeCommande.COMMANDE_ENVOYER_MESSAGE);
            sortie.writeUTF(pseudo);
            sortie.writeUTF(msg);
        } catch (IOException ex) {
            new TraiteException(ex, "envoyerMessage");
        }
    }

    void expulser(String nomCanal,String pseudo) {
        try {
            sortie.writeShort(CodeCommande.COMMANDE_EXPULSER_UTILISATEUR_CANAL);
            sortie.writeUTF(nomCanal);
            sortie.writeUTF(pseudo);
        } catch (IOException ex) {
            new TraiteException(ex, "expulser");
        }
    }

    void op(String nomCanal, String pseudo) {
        try {
            sortie.writeShort(CodeCommande.COMMANDE_NOUVEAU_SUPERUTILISATEUR);
            sortie.writeUTF(nomCanal);
            sortie.writeUTF(pseudo);
        } catch (IOException ex) {
            new TraiteException(ex, "op");
        }
    }

    void quitterCanal(String canal) {
        try {
            sortie.writeShort(CodeCommande.COMMANDE_QUITTER_CANAL);
            sortie.writeUTF(canal);
        } catch (IOException ex) {
            new TraiteException(ex, "quitterCanal");
        }
    }

    void supprimerCanal(String nomCanal) {
        try {
            sortie.writeShort(CodeCommande.COMMANDE_SUPPRIMER_CANAL);
            sortie.writeUTF(nomCanal);
        } catch (IOException ex) {
            new TraiteException(ex, "supprimmerCanal");
        }
    }

    
    private void traiterCommandes(short commande) throws IOException {
        String nomCanal ;
        String pseudo ;
        switch (commande){
            case CodeCommande.COMMANDE_ERREUR_INSCRIPTION :
                gui.erreurInscription();
                break;
            case CodeCommande.COMMANDE_INSCRIPTION_OK :
                connecte = true;
                gui.inscriptionOk();
                break;
            case CodeCommande.COMMANDE_ERREUR_CONNECTION :
                gui.erreurConnection();
                break;
            case CodeCommande.COMMANDE_CONNECTION_OK :
                connecte = true;
                gui.connectionOk();
                break;
            case CodeCommande.COMMANDE_RAFFRAICHIR_CANAL :
                nomCanal = entree.readUTF() ;
                int taille = entree.readInt() ;
                Vector<String> vect = new Vector() ;
                for (int i=0 ; i<taille ; i++)
                {
                    vect.add(entree.readUTF());
                }
                Collections.sort(vect);
                gui.rafraichirCanal(nomCanal,vect);
                break;
            case CodeCommande.COMMANDE_RAFFRAICHIR_MESSAGE_CANAL :
                pseudo = entree.readUTF();
                nomCanal = entree.readUTF();
                String msg = entree.readUTF();
                gui.rafraichirMessageCanal(pseudo,nomCanal,msg);
                break;
            case CodeCommande.COMMANDE_ERREUR_UTILISATEUR_BANNI :
                gui.erreurBanni();
                break;
            case CodeCommande.COMMANDE_ERREUR_UTILISATEUR_EXPULSER :
                nomCanal = entree.readUTF();
                gui.erreurExpulser(nomCanal);
                break;
            case CodeCommande.COMMANDE_BANNIR_UTILISATEUR_OK:
                gui.bannirOk();
                break;
            case CodeCommande.COMMANDE_ERREUR_DROITS_INSUFFISANTS_CANAL :
                gui.erreurDroitsInsufisant();
                break;
            case CodeCommande.COMMANDE_RAFFRAICHIR_MESSAGE_UTILISATEUR :
                pseudo = entree.readUTF();
                String pseudoReceveur = entree.readUTF();
                String message = entree.readUTF();
                gui.rafraichirMessageutilisateur(pseudo , pseudoReceveur ,  message);
                break ;
            case CodeCommande.COMMANDE_DIALOGUER :
                pseudo = entree.readUTF() ;
                gui.dialoguer(pseudo);
                break;
            case CodeCommande.COMMANDE_CANAL_SUPPRIME :
                nomCanal = entree.readUTF();
                gui.supprimerCanal(nomCanal);
                break ;
            case CodeCommande.COMMANDE_DEBANNIR_UTILISATEUR_OK :
                gui.debannirOK();
                break ;
        }
    }

}
   